package pl.edu.mimuw.irs.core.model.design.net;

import java.util.LinkedHashMap;
import java.util.Map;

import pl.edu.mimuw.irs.core.global.IDManager;
import pl.edu.mimuw.irs.core.model.design.exception.InternalDesignException;
import pl.edu.mimuw.irs.core.model.design.exception.InternalDesignException.DesignCause;
import pl.edu.mimuw.irs.core.model.design.net.refinement.IRSActivityChildren;
import pl.edu.mimuw.irs.core.model.design.resource.Requirement;
import pl.edu.mimuw.irs.core.model.design.resource.Requirements;
import pl.edu.mimuw.irs.core.util.Position;

/**
 * @author Jakub Rauch
 * Created on: 2009-05-07
 */
public class IRSRequirement extends IRSPlace {
	
	private static final long serialVersionUID = 3997013035980030550L;
	
	// *** Attributes
	private Requirements requirements;
	private Map<Requirement, Integer> requirementsMap;
	private int timeUnits;
	private double deviation;
	
	// Getters and setters
	public Requirements getRequirements() {
		if (requirements == null) requirements = new Requirements();
		return requirements;
	}
	public Map<Requirement, Integer> getRequirementsMap() {
		requirementsMap = new LinkedHashMap<Requirement, Integer>();
		for (Requirement requirement : getRequirements()) {
			Integer value = requirementsMap.get(requirement);
			if (value == null) {
				requirementsMap.put(requirement, new Integer(1));
			} else {
				requirementsMap.put(requirement, value + 1);
			}
		}
		return requirementsMap;
	}
	public void setRequirements(Requirements requirements) {
		this.requirements = requirements;
	}
	public int getTimeUnits() {
		return timeUnits;
	}
	public void setTimeUnits(int timeUnits) {
		this.timeUnits = timeUnits;
	}
	public double getDeviation() {
		return deviation;
	}
	public void setDeviation(double deviation) {
		this.deviation = deviation;
	}
	
	// *** Constructors

	public IRSRequirement(IDManager idManager, String id, Position position, int tokens, 
			int timeUnits, Requirements requirements) {
		super(idManager, id, position, tokens);
		this.timeUnits = timeUnits;
		this.requirements = requirements;
	}
	
	public IRSRequirement(IDManager idManager, String id, Position position, int tokens, int timeUnits) {
		super(idManager, id, position, tokens);
		setTimeUnits(timeUnits);
	}
	
	public IRSRequirement(IDManager idManager, String id, Position position, int tokens) {
		this(idManager, id, position, tokens, 10);
	}
	
	public IRSRequirement(IDManager idManager, Position position, int tokens) {
		this(idManager, null, position, tokens);
	}

	public IRSRequirement(IDManager idManager, Position position) {
		this(idManager, idManager.getNewId(), position, 0);
	}

	public IRSRequirement(IDManager idManager) {
		this(idManager, new Position());
	}
	
	/** Copying constructor. */
	public IRSRequirement(IRSRequirement requirement) {
		super(requirement);
		this.deviation = requirement.deviation;
		this.requirements = requirement.requirements.clone();
		this.timeUnits = requirement.timeUnits;
	}
	
	// *** Methods

	public IRSActivity getActivity() {
		try {
			return ((IRSActivityChildren)getParent().getChildren()).getActivity();
		} catch (Exception ex) {
			throw new InternalDesignException(DesignCause.CO_ACTIVITY_NOT_FOUND, ex, this);
		}
	}
//	
//	public AtomicSubnet getAtomicWorkflow(AtomicSubnet atomicSubnet) {
//		if (Refinement.NONE.equals(getRefinement())) {
//			Place place = copy(atomicSubnet);
//			atomicSubnet.addPlace(place);
//			atomicSubnet.getPlacesMap().put(this, place);
//			Map<IRSTransition, Transition> transitionsMap = atomicSubnet.getTransitionsMap();
//			for (IRSArc arc : getAtomicIncomingArcs()) {
//				Transition transition = transitionsMap.get(Converter.asIRSTransition(arc.getTransition()));
//				if (transition != null) {
//					atomicSubnet.connect(transition, place, getRequirements().size());
//				}
//			}
//			for (IRSArc arc : getAtomicOutgoingArcs()) {
//				Transition transition = transitionsMap.get(Converter.asIRSTransition(arc.getTransition()));
//				if (transition != null) {
//					atomicSubnet.connect(place, transition, getRequirements().size());
//				}
//			}
//		} else {
//			for (IRSNode node : getChildren()) {
//				atomicSubnet = node.getAtomicWorkflow(atomicSubnet);
//			}
//		}
//		return atomicSubnet;
//	}
}
